<!DOCTYPE HTML>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  
  <title>SpringMVC › 但行好事，莫问前程</title>
  <meta name="author" content="fengbo">
  
  <meta name="description" content="不想当架构师的程序员不是好厨师 ，不认为PHP是世界上最好的编程语言的Python开发者不是一个好的Javaer。">
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <meta property="og:title" content="SpringMVC">
  <meta property="og:site_name" content="但行好事，莫问前程">

  
    <meta property="og:image" content="undefined">
  

  <link href="/favicon.png" rel="icon">
  <link rel="alternate" href="/atom.xml" title="但行好事，莫问前程" type="application/atom+xml">
  <link rel="stylesheet" href="/css/style.css" media="screen" type="text/css">
  <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  

</head>
</html>

<body>
  <header id="header"><div class="meta inner">
  <h1><a href="/">但行好事，莫问前程</a></h1>
  <h2><a href="/">CV工程师，了解面向Google编程的基本原理，有三年使用Google经验，在通往程序员的道路上艰难的爬行着。</a></h2>
  <nav id="main-nav">
    <ul>
      
      <li><a href="/">Home</a></li>
      
      <li><a href="/archives">Archives</a></li>
      
      <li><a href="/atom.xml">RSS</a></li>
      
    </ul>
    <div class="clearfix"></div>
  </nav>
</div>
<div class="clearfix"></div>
</header>
  <div id="content" class="inner">
    <div id="main-col" class="alignleft"><div id="wrapper"><article class="post">
  <div class="post-content">
    <header>
      
  
    <h1 class="title">SpringMVC</h1>
  

      
        <time datetime="2018-03-20T12:42:35.000Z">2018-03-20</time>
      
    </header>
    <div class="entry">
      
        <h2 id="SpringMVC请求处理流程"><a href="#SpringMVC请求处理流程" class="headerlink" title="SpringMVC请求处理流程"></a>SpringMVC请求处理流程</h2><ul>
<li>用户发起请求到前端控制器(FrontController)。</li>
<li>前端控制器根据用户的URL请求一个或多个处理器映射器(HandlerMapping)，处理器映射器根据XML配置或者注解来进行查找匹配该URL的Handler，并返回给前端控制器。</li>
<li>前端控制器调用处理器适配器(HandlerAdaptor)去执行Handler，并返回一个ModelAndView。</li>
<li>如果ModelAndView中直接返回了具体的View实例，那么，前端控制器将直接从ModelAndView中获取该View并渲染视图。</li>
<li>如果返回的是逻辑视图名，前端控制器将请求视图解析器(ViewResolver)，将逻辑视图名解析成真正的视图。<a id="more"></a>
</li>
</ul>
<p><img src="/img/SpringMVC请求流程.JPG"></p>
<h2 id="SpringMVC主要组件"><a href="#SpringMVC主要组件" class="headerlink" title="SpringMVC主要组件"></a>SpringMVC主要组件</h2><p><img src="/img/SpringMVC主要组件.JPG"></p>
<ul>
<li>DispatcherServlet：整个框架的前端控制器，负责接收并分发所有Web请求。</li>
<li>HandlerMapping：帮助DispatcherServlet进行Web请求的URL到具体处理类的匹配。</li>
<li>HandlerAdaptor：使用适配器模式屏蔽不同Handler类型给DispatcherServlet造成的困扰。</li>
<li>Controller：SpringMVC框架支持的用于处理具体Web请求的Handler类型之一。</li>
<li>ModuleAndView：包含视图相关内容（可以使逻辑视图名称，也可以是具体的View实例）和模型数据。</li>
<li>ViewResolver：根据Controller所返回的ModuleAndView中的逻辑视图名，返回一个可用的View实例。</li>
<li>View：进行视图渲染，将提供的视图模板和最终提供的模型数据合并到一起，形成最终输出结果页面。</li>
</ul>
<h2 id="SpringMVC其它组件"><a href="#SpringMVC其它组件" class="headerlink" title="SpringMVC其它组件"></a>SpringMVC其它组件</h2><p><img src="/img/SpringMVC其它组件.JPG"></p>
<h3 id="文件上传"><a href="#文件上传" class="headerlink" title="文件上传"></a>文件上传</h3><ol>
<li>当Web请求到达DispatcherServlet并等待处理时，DispatcherServlet会先检查能否从自己的WebApplicationContext中找到一个名为multipartResolver的MultipartResolver(位于HandlerMapping之前)实例。</li>
<li>如果获得了该实例，DispatcherServlet将通过该实例的isMultipart(request)方法检测当前web请求是否为multipart类型。</li>
<li>如果是，DispatcherServlet将调用该实例的resolveMultipart(request)方法，并返回一个MultipartHttpServletRequest，否则，直接返回最初的HttpServletRequest。</li>
<li>MultipartHttpServletRequest的getFile(String)方法可以获得一个MultipartFile对象，然后就可以根据具体的业务对MultipartFile进行操作了。</li>
</ol>
<h3 id="拦截器-HandlerInterceptor"><a href="#拦截器-HandlerInterceptor" class="headerlink" title="拦截器(HandlerInterceptor)"></a>拦截器(HandlerInterceptor)</h3><ul>
<li>HandlerInterceptor接口中的方法<ul>
<li>boolean preHandler(..)：该方法在HandlerAdaptor调用具体的Handler处理Web请求之前执行。返回true表示运行后续流程继续执行；false表示不允许。</li>
<li>void postHandler(..)：HandlerAdaptor调用Handler处理Web请求后，视图的解析和渲染之前执行。通过该方法可以获取Handler执行后的结果，即ModuleAndView。所以该方法可以对ModuleAndView进行添加统一的模型数据、数据变更等操作。</li>
<li>void afterCompletion(..)：在框架整个处理流程结束之后，或者说视图渲染完了的时候，不管是否发生异常，该方法都将被执行。如果处理时异常结束的话，我们可以在该方法中获取异常（Exception）的引用并对其进行统一处理。另外，如果Web请求过程中有相应的资源需要清理的话，也可以在这里完成。</li>
</ul>
</li>
<li>SpringMVC内部实现<ul>
<li>UserRoleAuthorizationInterceptor：通过HttpServletRequest的isUserInRole(..)方法，使用指定的一组用户角色(UserRoles)对当前请求进行验证。如果验证不通过将默认返回403状态码，即forbidden。</li>
<li>WebContextInterceptor：1.<b>检查请求方法类型是否在支持的方法之列。</b>如果当前请求的方法类型超出我们通过setSupportedMethods(..)方法指定的范围，那么将抛出HttpRequestMethodNotSupportedException从而阻断后续处理流程；2.<b>检查必要的Session实例。</b>如果我设置了requireSession属性为true，同时又发现当前请求不能返回一个已经存在的Session实例，将会抛出HttpSessionRequiredException阻断后续执行；3.<b>检查缓存时间并通过设置相应的HTTP头(Header)的方式控制缓存行为。</b></li>
</ul>
</li>
</ul>
<h3 id="拦截器和过滤器的区别"><a href="#拦截器和过滤器的区别" class="headerlink" title="拦截器和过滤器的区别"></a>拦截器和过滤器的区别</h3><ul>
<li>拦截器是基于Java的反射机制，即使用SpringAOP机制实现，而过滤器是基于函数回调。</li>
<li>拦截器是Spring组件，配置在Spring文件中，可以使用Spring的资源和对象（即拦截器可以获取IoC容器中的各个bean）。</li>
<li>过滤器在Servlet执行前和执行后执行，所以SpringMVC的全局异常处理无法处理过滤器中抛出的异常。</li>
</ul>
<p><img src="/img/SpringMVC拦截器与过滤器.JPG"></p>
<h2 id="SpringMVC父子容器"><a href="#SpringMVC父子容器" class="headerlink" title="SpringMVC父子容器"></a><a href="https://blog.csdn.net/lemontreey/article/details/53079757" target="_blank" rel="noopener">SpringMVC父子容器</a></h2><p>在Spring整体框架的核心概念中，容器是核心思想，负责管理Bean的整个生命周期。而在一个项目中，容器不一定只有一个，Spring中可以包括多个容器，而且容器有上下层关系，目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架，那么它其实就是两个容器，Spring是父容器，SpringMVC是其子容器，<b>并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的，而在SpringMVC容器中注册的Bean对于Spring父容器中是不可见的，也就是子容器可以看见父容器中的注册的Bean，反之就不行。</b></p>

      
    </div>
      
      <footer>
        
        
  
  <div class="tags">
    <a href="/tags/JavaWeb/">JavaWeb</a>
  </div>

        
  <div class="addthis addthis_toolbox addthis_default_style">
    
      <a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
    
    
      <a class="addthis_button_tweet"></a>
    
    
      <a class="addthis_button_google_plusone" g:plusone:size="medium"></a>
    
    
      <a class="addthis_button_pinterest_pinit" pi:pinit:layout="horizontal"></a>
    
    <a class="addthis_counter addthis_pill_style"></a>
  </div>
  <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js"></script>

      
      <div class="clearfix"></div>
      </footer>
  </div>
</article>

<!-- 来必力City版安装代码 -->
<!-- <div id="lv-container" data-id="city" data-uid="MTAyMC8yOTQ5MS82MDU5">
<script type="text/javascript">
   (function(d, s) {
       var j, e = d.getElementsByTagName(s)[0];

       if (typeof LivereTower === 'function') { return; }

       j = d.createElement(s);
       j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
       j.async = true;

       e.parentNode.insertBefore(j, e);
   })(document, 'script');
</script>
<noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
</div> -->
<!-- City版安装代码已完成 -->

</div></div>
    <aside id="sidebar" class="alignright">
  
<div class="widget tagcloud">
  <h3 class="title">文章分类</h3>
  <div class="entry">
    <a href="/tags/JavaWeb/" style="font-size: 17.14px;">JavaWeb</a> <a href="/tags/Java基础/" style="font-size: 15.71px;">Java基础</a> <a href="/tags/Java高级特性/" style="font-size: 15.71px;">Java高级特性</a> <a href="/tags/Python/" style="font-size: 10px;">Python</a> <a href="/tags/Spring基础/" style="font-size: 14.29px;">Spring基础</a> <a href="/tags/WebRTC/" style="font-size: 10px;">WebRTC</a> <a href="/tags/其它/" style="font-size: 20px;">其它</a> <a href="/tags/分布式/" style="font-size: 11.43px;">分布式</a> <a href="/tags/硬件/" style="font-size: 12.86px;">硬件</a> <a href="/tags/计算机基础/" style="font-size: 18.57px;">计算机基础</a> <a href="/tags/设计模式/" style="font-size: 17.14px;">设计模式</a>
  </div>
</div>



    <div class="widget tagcloud">
    <h3 class="title">电子书</h3>
    <ul class="entry">
      <li class='link'><a href='http://www.duokan.com/' target="_blank">多看阅读</a>&nbsp;&nbsp;<a href='https://read.douban.com/' target="_blank">豆瓣阅读</a>&nbsp;&nbsp;<a href='http://e.dangdang.com/' target="_blank">当当阅读</a></li>
      <li class='link'><a href='http://www.ituring.com.cn/' target="_blank">图灵社区</a>&nbsp;&nbsp;<a href='https://www.epubit.com/' target="_blank">异步社区</a>&nbsp;&nbsp;<a href='https://www.geekbang.org/' target="_blank">极客空间</a></li>
    </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">友情链接</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://www.cnblogs.com/jietang/' target="_blank">唐洁的博客</a></li>
        
          <li class='link'><a href='http://rednaxelafx.iteye.com/' target="_blank">R大的博客</a></li>
        
          <li class='link'><a href='http://www.hollischuang.com/' target="_blank">阿里大神的博客</a></li>
        
          <li class='link'><a href='http://blog.csdn.net/IT_faquir/' target="_blank">IT_faquir的专栏</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">思维导图</h3>
      <ul class="entry">
        
          <li class='link'><a href='https://fengbo4213.github.io/img/开源协议.png' target="_blank">开源协议简介</a></li>
        
          <li class='link'><a href='https://www.processon.com/diagraming/5b0cf757e4b009aef58d4b9d' target="_blank">我的知识体系</a></li>
        
          <li class='link'><a href='https://www.processon.com/view/link/5a2a00e5e4b015e677290b4f' target="_blank">简单的网站架构</a></li>
        
      </ul>
  </div>


  
  <div class="widget tag">
    <h3 class="title">在线手册</h3>
      <ul class="entry">
        
          <li class='link'><a href='http://v3.bootcss.com/' target="_blank">BootStrap官方手册</a></li>
        
          <li class='link'><a href='http://www.iconfont.cn/http://element.eleme.io/#/zh-CN/' target="_blank">阿里巴巴矢量图标库</a></li>
        
      </ul>
  </div>


  
<div class="widget tag">
  <h3 class="title">最新文章</h3>
  <ul class="entry">
    
      <li>
        <a href="/2123/08/30/基础之MySQL原理/">MySQL原理</a>
      </li>
    
      <li>
        <a href="/2024/01/01/其它之ClickHouse索引/">ClickHouse索引</a>
      </li>
    
      <li>
        <a href="/2023/12/17/其它之MySQL线程池/">MySQL线程池</a>
      </li>
    
      <li>
        <a href="/2023/12/16/其它之InnoDB性能优化基础/">InnoDB性能优化基础</a>
      </li>
    
      <li>
        <a href="/2023/12/03/其它之Java8之后的版本新特性/">Java8之后的版本新特性</a>
      </li>
    
  </ul>
</div>

</aside>
    <div class="clearfix"></div>
  </div>
  <footer id="footer" class="inner"><div class="alignleft">
  
  &copy; 2024 fengbo
  
</div>
<div class="clearfix"></div></footer>
  <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>



</body>
</html>

